Skip to content

feat(ssd1327): Add blink animation example with framebuf scaling.#420

Open
MatteoCnda1 wants to merge 1 commit intomainfrom
feat/ssd1327-blink-animation
Open

feat(ssd1327): Add blink animation example with framebuf scaling.#420
MatteoCnda1 wants to merge 1 commit intomainfrom
feat/ssd1327-blink-animation

Conversation

@MatteoCnda1
Copy link
Copy Markdown
Contributor

Summary

Rapatriate and clean up the blink animation example from micropython-steami-sample. Closes #407

Changes

  • Added lib/ssd1327/examples/blink_animation.py based on SCREEN/steami_animation/steami_animation.py
  • Translated all comments to English
  • Replaced sleep with sleep_ms
  • Added try/finally to clear display on exit
  • Removed commented-out scaling code and reimplemented it properly
  • Added SCALE = 6 for a 96x96px eye on the 128x128 round screen
  • Smoothed animation from 3 frames to 5 (added EYE_SQUINT intermediate state)
  • Added @micropython.native on draw_eye() for faster rendering
  • Added module-level docstring

Checklist

  • ruff check passes
  • python -m pytest tests/ -k mock -v passes
  • Tested on hardware (STM32WB55 / STeaMi board)
  • README updated (if adding/changing public API) — README table to update
  • Examples added (lib/ssd1327/examples/blink_animation.py)
  • Commit messages follow <scope>: <Description.> format

@MatteoCnda1 MatteoCnda1 requested review from Charly-sketch, Kaanoz-en and nedseb and removed request for Kaanoz-en April 20, 2026 13:20
@MatteoCnda1 MatteoCnda1 force-pushed the feat/ssd1327-blink-animation branch from 0c48ca6 to b361f99 Compare April 20, 2026 13:21
@Kaanoz-en Kaanoz-en requested a review from Copilot April 20, 2026 13:23
@MatteoCnda1 MatteoCnda1 changed the title feat(ssd1327): Add blink animation example using framebuf blit and pi… feat(ssd1327): Add blink animation example with framebuf scaling. Apr 20, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new SSD1327 driver example demonstrating a scaled bitmap blink animation using framebuf buffers and blit() on the STeaMi 128×128 OLED, intended to replace/clean up an example previously living in micropython-steami-sample (Issue #407).

Changes:

  • Added lib/ssd1327/examples/blink_animation.py implementing a multi-frame eye blink animation.
  • Uses sleep_ms timing and a try/finally to clear the display on exit.
  • Implements pixel-by-pixel scaling into an intermediate framebuffer prior to blitting.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +204 to +213
scaled_bitmap = bytearray((scaled_w * scaled_h) // 8)
scaled_buf = framebuf.FrameBuffer(
scaled_bitmap, scaled_w, scaled_h, framebuf.MONO_HLSB
)

# Scale up pixel by pixel
for y in range(EYE_H):
for x in range(EYE_W):
if buf.pixel(x, y):
scaled_buf.fill_rect(x * SCALE, y * SCALE, SCALE, SCALE, 1)
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

display.framebuf is GS4_HMSB (4-bit grayscale, values 0–15), but scaled_buf is created as MONO_HLSB and the scaling writes color 1. When blitted, the ‘on’ pixels will map to value 1, which is almost black on this display (making the eye very hard to see). Consider either scaling into a GS4_HMSB buffer and using color 15 for ‘on’ pixels, or providing a palette to blit() that maps 0→0 and 1→15.

Suggested change
scaled_bitmap = bytearray((scaled_w * scaled_h) // 8)
scaled_buf = framebuf.FrameBuffer(
scaled_bitmap, scaled_w, scaled_h, framebuf.MONO_HLSB
)
# Scale up pixel by pixel
for y in range(EYE_H):
for x in range(EYE_W):
if buf.pixel(x, y):
scaled_buf.fill_rect(x * SCALE, y * SCALE, SCALE, SCALE, 1)
scaled_bitmap = bytearray((scaled_w * scaled_h) // 2)
scaled_buf = framebuf.FrameBuffer(
scaled_bitmap, scaled_w, scaled_h, framebuf.GS4_HMSB
)
# Scale up pixel by pixel
for y in range(EYE_H):
for x in range(EYE_W):
if buf.pixel(x, y):
scaled_buf.fill_rect(x * SCALE, y * SCALE, SCALE, SCALE, 15)

Copilot uses AI. Check for mistakes.
Comment on lines +202 to +207
scaled_w = EYE_W * SCALE
scaled_h = EYE_H * SCALE
scaled_bitmap = bytearray((scaled_w * scaled_h) // 8)
scaled_buf = framebuf.FrameBuffer(
scaled_bitmap, scaled_w, scaled_h, framebuf.MONO_HLSB
)
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

draw_eye() allocates a new scaled_bitmap bytearray and FrameBuffer on every frame. For an animation loop this creates avoidable GC pressure and can cause stutters on constrained boards. Consider pre-scaling/caching the scaled framebuffers once (e.g., at module init) and only blitting in the hot loop, or reusing a single preallocated buffer with fill(0) each frame.

Copilot uses AI. Check for mistakes.
Comment on lines +32 to +40
# === Eye bitmaps (MONO_HLSB, 16x16, 2 bytes per row) ===

EYE_OPEN = bytearray(
[
0b00000000,
0b00000000,
0b00111111,
0b10000000,
0b01000000,
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says the eye bitmaps are “16x16, 2 bytes per row”, which implies 32 bytes total for MONO_HLSB, but each bitmap literal below contains 33 bytes (based on the number of entries). This extra trailing byte is unused and can be confusing; consider trimming to 32 bytes or updating the dimensions/comment to match the actual data layout.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +5
"""Blink animation example using framebuf blit and pixel scaling on SSD1327 OLED.

Displays a scaled 16x16 eye bitmap centered on the 128x128 round OLED screen
and animates a smooth blink sequence by cycling through five eye states.

Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description/issue checklist mentions updating lib/ssd1327/README.md examples table, but this PR only adds the example file. Please add blink_animation.py to the README Examples table (or update the PR description if that task is intentionally out of scope).

Copilot uses AI. Check for mistakes.
Comment on lines +215 to +216
x_offset = (128 - scaled_w) // 2
y_offset = (128 - scaled_h) // 2
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hard-codes 128 for centering. Since the display object already exposes display.width / display.height, using those would keep the example correct if the driver is instantiated with a different resolution (and avoids duplicating the docstring assumption).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(ssd1327): Rapatriate blink animation example from micropython-steami-sample.

2 participants